package com.eis.admin.mvc.controller;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.eis.admin.mvc.bean.BizGroupBean;
import com.eis.admin.mvc.bean.FilterRuleEditBean;
import com.eis.admin.mvc.bean.FunctionBean;
import com.eis.admin.mvc.common.utils.MVCConstants;
import com.eis.admin.mvc.controller.base.MVCBaseController;
import com.eis.function.out.rule.comparator.common.RuleComparator;
import com.eis.function.out.rule.model.FilterRule;
import com.eis.function.out.rule.model.FilterRules;
import com.eis.persist.dao.FunctionDAO;
import com.eis.persist.dao.UserDAO;
import com.eis.persist.dao.UserFunctionDAO;
import com.eis.persist.dao.impl.FunctionDAOImpl;
import com.eis.persist.dao.impl.UserDAOImpl;
import com.eis.persist.dao.impl.UserFunctionDAOImpl;
import com.eis.persist.model.function.PersistFunctionSchema;
import com.eis.persist.model.user.PersistFunctionFilterRule;
import com.eis.persist.model.user.PersistUser;
import com.eis.util.XmlUtil;

@Controller
public class AuthorizationEngineController extends MVCBaseController {
	@SuppressWarnings("unused")
	private static final Logger logger = LoggerFactory.getLogger(AuthorizationEngineController.class);
	private UserDAO userDAO;
	private XmlUtil xmlUtil;
	public void setRuleUtil(XmlUtil xmlUtil) {
		this.xmlUtil = xmlUtil;
	}

	@Override
	public void setFunctionDataSource(JdbcTemplate functionDataSource) {
		this.functionDataSource = functionDataSource;
		userDAO = new UserDAOImpl(this.functionDataSource);
	}
	
	@RequestMapping(value = "/editFilterRule")
	public ModelAndView editFilterRule(@ModelAttribute("editFilterRuleBean") FilterRuleEditBean filterRuleEditBean, Model model, HttpServletRequest request) {
		PersistUser currentUser = super.getCurrentUser(request);
		
		List<BizGroupBean> existGroups = userDAO.getBizGroupForList(null, currentUser.getBizGroup().getId());
		model.addAttribute("bizGroupList", existGroups);

		if (filterRuleEditBean == null) {
			filterRuleEditBean = new FilterRuleEditBean();
		}
		
		if (filterRuleEditBean.getBizGroupId() == 0) {
			int bizGroupId = 0;
			if (request.getAttribute("bizGroupId") != null && ((Integer)request.getAttribute("bizGroupId")) > 0) {
				bizGroupId = (Integer)request.getAttribute("bizGroupId");
			} else if (request.getParameter("bizGroupId") != null 
					&& request.getParameter("bizGroupId").trim().length() > 0
					&& Integer.valueOf(request.getParameter("bizGroupId")) > 0) {
				bizGroupId = Integer.valueOf(request.getParameter("bizGroupId"));
			}
			filterRuleEditBean.setBizGroupId(bizGroupId);
		}
		
		if (filterRuleEditBean.getBizGroupId() > 0) {
			boolean idAvaliable = false;
			for (BizGroupBean oneBean : existGroups) {
				if (oneBean.getId() == filterRuleEditBean.getBizGroupId()) {
					filterRuleEditBean.setBizGroupName(oneBean.getName());
					idAvaliable = true;
				}
			}
			
			if (!idAvaliable) filterRuleEditBean.setBizGroupId(0);
		}
		
		if (filterRuleEditBean.getBizGroupId() == 0) {
			filterRuleEditBean.setFunctionId("");
		} else {
			UserFunctionDAO userFunctionDAO = new UserFunctionDAOImpl(functionDataSource);
			List<FunctionBean> functionList = userFunctionDAO.getFunctionsForList(filterRuleEditBean.getBizGroupId(), 0, 1000, null);
			model.addAttribute("functionList", functionList);
			
			boolean idAvaliable = false;
			for (FunctionBean functionBean : functionList) {
				if (functionBean.getFunctionID().equals(filterRuleEditBean.getFunctionId())) {
					idAvaliable = true;
					filterRuleEditBean.setFunctionName(functionBean.getFunctionName());
				}
			}
			
			if (!idAvaliable) {
				filterRuleEditBean.setFunctionId("");
			} else {
				// load function schema
				FunctionDAO functionDAO = new FunctionDAOImpl(functionDataSource);
				List<PersistFunctionSchema> persistFunctionSchemas = functionDAO.getFunctionSchemaByFunctionId(filterRuleEditBean.getFunctionId());
				
				model.addAttribute("functionSchemaList", persistFunctionSchemas);
				// Comparator List
				List<String> comparatorList = new ArrayList<String>();
				for (RuleComparator comparator : RuleComparator.values()) {
					comparatorList.add(comparator.name());
				}
				model.addAttribute("comparatorList", comparatorList);
				// load parent rules
				List<PersistFunctionFilterRule> parentRules = userDAO.loadParentFilterRule(
						filterRuleEditBean.getBizGroupId(), 
						filterRuleEditBean.getFunctionId(),
						currentUser.getBizGroup().getId());
				List<FilterRuleEditBean> extendFilterRules = new ArrayList<FilterRuleEditBean>();
				for (PersistFunctionFilterRule parentRule : parentRules) {
					FilterRuleEditBean bean = new FilterRuleEditBean();
					bean.setBizGroupId(parentRule.getBizGroupid());
					bean.setBizGroupName(parentRule.getGroupName());
					bean.setEditAble(parentRule.getEditAble());
					FilterRules parentFilterRules = (FilterRules) xmlUtil.parseXml(parentRule.getRulexml());
					if (parentFilterRules != null 
								&& parentFilterRules.getFilterRules() 
								!= null && parentFilterRules.getFilterRules().size() > 0) {
						bean.setFilterRules(parentFilterRules.getFilterRules());

						extendFilterRules.add(bean);
					}
				}
				model.addAttribute("extendFilterRules", extendFilterRules);
				// load rule
				PersistFunctionFilterRule persistFunctionFilterRule 
					= userDAO.loadFunctionFilterRule(filterRuleEditBean.getBizGroupId(), filterRuleEditBean.getFunctionId());
				
				if (persistFunctionFilterRule != null) {
					FilterRules filterRules = (FilterRules) xmlUtil.parseXml(persistFunctionFilterRule.getRulexml());
					filterRuleEditBean.setFilterRules(filterRules.getFilterRules());
				} else {
					filterRuleEditBean.setFilterRules(new ArrayList<FilterRule>());
				}
				
				UserDAO userDAO1 = new UserDAOImpl(this.functionDataSource,
						((PersistUser) request.getSession().getAttribute(
								MVCConstants.USER_SESSION_KEY)).getName());
				if ("addARule".equals(filterRuleEditBean.getOperation())) {
					FilterRules filterRules;
					int id = 1;
					if (persistFunctionFilterRule != null) {
						filterRules = (FilterRules) xmlUtil.parseXml(persistFunctionFilterRule.getRulexml());
						id = persistFunctionFilterRule.getMaxRuleId() + 1;
					} else {
						filterRules = new FilterRules();
						filterRules.setFilterRules(new ArrayList<FilterRule>());
					}

					FilterRule newFilterRule = new FilterRule();
					newFilterRule.setRuleId(id);
					newFilterRule.setComparator(filterRuleEditBean.getNewRuleComparator());
					newFilterRule.setCompareData(filterRuleEditBean.getNewRuleValue());
					newFilterRule.setFieldName(filterRuleEditBean.getNewRuleFieldName());
					filterRules.getFilterRules().add(newFilterRule);
					
					
					userDAO1.updateFilterRule(
							filterRuleEditBean.getBizGroupId(), 
							filterRuleEditBean.getFunctionId(), 
							xmlUtil.toXml(filterRules), 
							id);
					
					filterRuleEditBean.setFilterRules(filterRules.getFilterRules());
				} else if ("deleteRule".equals(filterRuleEditBean.getOperation1())) {
					FilterRules filterRules;
					if (persistFunctionFilterRule != null) {
						filterRules = (FilterRules) xmlUtil.parseXml(persistFunctionFilterRule.getRulexml());
						List<FilterRule> deletedList = new ArrayList<FilterRule>();
						try {
							int deleteId = Integer.parseInt(filterRuleEditBean.getOperationRuleId());
							for (FilterRule rule : filterRules.getFilterRules()) {
								if (deleteId != rule.getRuleId()) {
									deletedList.add(rule);
								}
							}
							filterRules.setFilterRules(deletedList);
							userDAO1.updateFilterRule(
									filterRuleEditBean.getBizGroupId(), 
									filterRuleEditBean.getFunctionId(), 
									xmlUtil.toXml(filterRules), 
									persistFunctionFilterRule.getMaxRuleId());
						} catch (Throwable t) {
							
						}
						filterRuleEditBean.setFilterRules(filterRules.getFilterRules());
					}
				} else if ("editRule".equals(filterRuleEditBean.getOperation2())) {
					FilterRules filterRules;
					if (persistFunctionFilterRule != null) {
						filterRules = (FilterRules) xmlUtil.parseXml(persistFunctionFilterRule.getRulexml());
						try {
							int deleteId = Integer.parseInt(filterRuleEditBean.getEditRuleId());
							for (FilterRule rule : filterRules.getFilterRules()) {
								if (deleteId == rule.getRuleId()) {
									rule.setComparator(filterRuleEditBean.getUpdateRuleComparator());
									rule.setCompareData(filterRuleEditBean.getUpdateRuleValue());
									rule.setFieldName(filterRuleEditBean.getUpdateRuleFieldName());
								}
							}
							userDAO1.updateFilterRule(
									filterRuleEditBean.getBizGroupId(), 
									filterRuleEditBean.getFunctionId(), 
									xmlUtil.toXml(filterRules), 
									persistFunctionFilterRule.getMaxRuleId());
						} catch (Throwable t) {
							
						}
						filterRuleEditBean.setFilterRules(filterRules.getFilterRules());
					}
				}
			}
		}
		
		
		return new ModelAndView("/bizgroup/editFilterRule", "command", filterRuleEditBean);
	}
}
